package com.abc.cloud.common.filter;

import cn.hutool.core.collection.CollUtil;
import com.abc.cloud.common.utils.UserHolder;
import com.abc.cloud.entity.PermsEntity;
import com.abc.cloud.service.PermsService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;   
import javax.servlet.http.HttpServletResponse;
import java.nio.file.AccessDeniedException;
import java.util.*;

@Slf4j
public class PathInterceptor implements HandlerInterceptor {

    private final Map<String, String> configAttributeMap = new HashMap<>();

    private final List<String> urls;
    private final PermsService permsService;

    public PathInterceptor(List<String> urls, PermsService permsService) {
        this.urls = urls;
        this.permsService = permsService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String str = request.getRequestURI();
        // 检查白名单
        for (String url : urls) {
            if (url.matches(str)){
                log.info("{}在白名单内，直接放行", str);
                return true;
            }
        }

        // 查询所有的路径的权限
        if (configAttributeMap.isEmpty()){
            List<PermsEntity> permsEntities = permsService.list(new QueryWrapper<PermsEntity>().eq("status", 1));
            for (PermsEntity permsEntity : permsEntities) {
                configAttributeMap.put(permsEntity.getPath(), permsEntity.getPerms());
            }
        }

        List<String> configAttributes = new ArrayList<>();
        String path = request.getRequestURI();
        AntPathMatcher pathMatcher = new AntPathMatcher();
        Iterator<String> iterator = configAttributeMap.keySet().iterator();
        // 获取访问该路径所需权限
        while (iterator.hasNext()) {
            String pattern = iterator.next();
            if (pathMatcher.match(pattern, path)) {
                configAttributes.add(configAttributeMap.get(pattern));
            }
        }

        if (CollUtil.isEmpty(configAttributes)) {
            log.info("该接口未被配置，直接放行");
            return true;
        }

        // 匹配用户是否有访问该路径的权限
        List<String> authorities = UserHolder.getAuthorities();
        for (String configAttribute : configAttributes) {
            log.info("需要的资源:{}", configAttribute);
            log.info("拥有的资源:{}", authorities);
            for (String grantedAuthority : authorities) {
                if (configAttribute.trim().equals(grantedAuthority)) {
                    return true;
                }
            }
        }

        throw new AccessDeniedException("抱歉，您没有访问权限");
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
